/**
 * @fileoverview
 * TODO doc me
 */


// Shortcuts
var trace = function(message) { YAHOO.log(message, "test"); };
var assert = YAHOO.util.Assert;


// ************************************************************
// MODULE TESTS
// ************************************************************


/**
 * TODO declare the class
 */
flyui.bdgp.Service.ModuleTests = function(){};


/** 
 * Test that the contents of the flyui.bdgp.Service module have been defined.
 */
flyui.bdgp.Service.ModuleTests.testModuleContents = function() {
	
	flyui.info("Test \"==== flyui.bdgp.Service ModuleTests :: testModuleContents ====\" started.");
	
	assert.isNotUndefined(flyui.bdgp.Service, "flyui.bdgp.Service is undefined");	
	
	assert.isNotUndefined(flyui.bdgp.Stage, "flyui.bdgp.Stage is undefined");
	
};


/**
 * TODO
 */
flyui.bdgp.Service.ModuleTestCase = function (){
	var testCase = new YAHOO.tool.TestCase({
		
		name: "=== flyui.bdgp.Service ModuleTests ===",
		
		testModuleContents : flyui.bdgp.Service.ModuleTests.testModuleContents
		
	});
	
	return testCase;
}

flyui.bdgp.ImageTests = function(){};

flyui.bdgp.ImageTests.setUpTest = function() {
	try {
		trace("setUp test");
	} catch (e) {
		flyui.err("setUp error, "+e.name+", "+e.message);
	}
};

flyui.bdgp.ImageTests.tearDownTest = function() {
	try {
		trace("tearDown test");
	} catch (e) {
		flyui.err("tearDown error, "+e.name+", "+e.message);
	}
};

flyui.bdgp.ImageTests.testImageClassDefinition = function() {
	flyui.info("Test \"==== flyui.bdgp ImageTests :: testImageClassDefinition ====\" started.");
	
	assert.isNotUndefined(flyui.bdgp.Stage.newInstancesFromSPARQLResults, "newInstancesFromSPARQLResults is undefined");
	
	var stage = new flyui.bdgp.Stage();
	assert.isNotUndefined(stage.stageName, "stage.stageName is undefined");
	assert.isNotUndefined(stage.images, "stage.images is undefined");
	assert.isNotUndefined(stage.addImage, "stage.addImage is undefined");		
};



flyui.bdgp.ImageTests.testStageAddImages = function(){
	flyui.info("Test \"==== flyui.bdgp ImageTests :: testStageAddImages ====\" started.");
	var stage = new flyui.bdgp.Stage();
	
	methods = ["addImage"];
	
	fields = ["images"];
	
	for (var i=0; i<methods.length; i++) {
		var add = methods [i];
		var field = fields[i];
		trace("method "+add+" field "+field);
		assert.isNotUndefined(stage[add]);
		assert.isNotUndefined(stage[field]);
		
		trace("adding foo");
		var fooImage = new Object();
		fooImage.fullImageURL = "foo"; 
		stage[add](fooImage);
		assert.areEqual(1, stage[field].length, "stage field "+field+" length not as expected");
		assert.areEqual(fooImage, stage[field][0], "stage "+field+" not as expected");

		trace("adding bar");
		var barImage = new Object();
		barImage.fullImageURL = "bar"; 
		
		stage[add](barImage);
		assert.areEqual(2, stage[field].length, "stage field "+field+" length not as expected");
		assert.areEqual(barImage, stage[field][1], "stage "+field+" not as expected");

		trace("adding duplicate foo");
		stage[add](fooImage); // try a duplicate
		assert.areEqual(2, stage[field].length, "stage field "+field+" length not as expected");
	}
	
};



flyui.bdgp.ImageTests.testNewImageFromSPARQLResults = function(){
	flyui.info("Test \"==== flyui.bdgp ImageTests :: testNewImageFromSPARQLResults ====\" started.");

	var testData = new flyui.bdgp.Service.TestData();
	
	var stages = flyui.bdgp.Stage.newInstancesFromSPARQLResults(testData.resultSet_CG10561);
	
	assert.areEqual(1, stages.length, "one stage expected");
	
	var stage = stages[0];
	
	assert.areEqual("stage13-16", stage.stageName, "stage name is not right");
	
	var images = stage.images;
	
	assert.areEqual(1, images.length, "one image expected");
	
	var image = images[0];
		
	flyui.bdgp.Service.TestData.compareImages(testData.img_CG10561, image);
};


flyui.bdgp.ImageTests.testNewImagesFromSPARQLResults = function(){
	flyui.info("Test \"==== flyui.bdgp ImageTests :: testNewImagesFromSPARQLResults ====\" started.");

	var testData = new flyui.bdgp.Service.TestData();
	var resultSet = testData.resultSet_CG12750;
	var stages = flyui.bdgp.Stage.newInstancesFromSPARQLResults(resultSet);
	
	assert.areEqual(5, stages.length, "one stage expected");	
	
	
	for (var s in stages) {
		var stage = stages[s];
		var images = stage.images;
		
		if (stage.stageName == "stage1-3") {
			log ("number of images " + images.length, "test");
			assert.areEqual(2, images.length, "eleven image expected");
			flyui.bdgp.Service.TestData.compareImageArrays(testData.stage_CG12750_1.images,images);
		}else if (stage.stageName == "stage4-6") {
			log ("number of images " + images.length, "test");
			assert.areEqual(1, images.length, "eleven image expected");
			flyui.bdgp.Service.TestData.compareImageArrays(testData.stage_CG12750_2.images,images);
		}else if (stage.stageName == "stage7-8") {
			log ("number of images " + images.length, "test");
			assert.areEqual(3, images.length, "eleven image expected");
			flyui.bdgp.Service.TestData.compareImageArrays(testData.stage_CG12750_3.images,images);
		}else if (stage.stageName == "stage11-12") {
			log ("number of images " + images.length, "test");
			assert.areEqual(3, images.length, "eleven image expected");
			flyui.bdgp.Service.TestData.compareImageArrays(testData.stage_CG12750_4.images,images);
		}else if (stage.stageName == "stage13-16") {
			log ("number of images " + images.length, "test");
			assert.areEqual(2, images.length, "eleven image expected");
			flyui.bdgp.Service.TestData.compareImageArrays(testData.stage_CG12750_5.images,images);
		}
		
	}
	
	
};

flyui.bdgp.Service.ImageTestCase = function() {
	
	var testCase = new YAHOO.tool.TestCase({
		
		name: "=== flyui.bdgp ImageTests ===",
		
		setUp : flyui.bdgp.ImageTests.setUpTest,
		
		tearDown : flyui.bdgp.ImageTests.tearDownTest,
		
		testImageClassDefinition : flyui.bdgp.ImageTests.testImageClassDefinition,
		
		testStageAddImages : flyui.bdgp.ImageTests.testStageAddImages,
				
		testNewImageFromSPARQLResults : flyui.bdgp.ImageTests.testNewImageFromSPARQLResults,
		
		testNewImagesFromSPARQLResults : flyui.bdgp.ImageTests.testNewImagesFromSPARQLResults
	});
	
	return testCase;
	
};


// ************************************************************
// SERVICE TESTS
// ************************************************************


/**
 * TODO
 */
flyui.bdgp.Service.ServiceTests = function(){};


/**
 * TODO doc me
 */
flyui.bdgp.Service.ServiceTests.testQuery = function(endpointURL, testCase){
	flyui.info("Test \"==== flyui.bdgp.Service ServiceTests :: testQuery ====\" started.");
		
	var service = new flyui.bdgp.Service(endpointURL);
	var query = "ASK { ?s ?p ?o }";
	
	var testOnSuccess = function(responseObject) {
		trace("resume test case (success)");
		testCase.resume(function() {
			
			// check status code			
			assert.areEqual(200, responseObject.status);
			
			// try parsing response text as json
			var resultSet = YAHOO.lang.JSON.parse(responseObject.responseText);
			
			// check json content
			assert.isTrue(resultSet["boolean"], "result set not as expected");
		});
	};
	
	var testOnFailure = function(responseObject) {
		trace("resume test case (failure)");
		testCase.resume(function() {
			// force failure
			assert.fail("request failed, status "+responseObject.status + " " +responseObject.statusText);
		});
	};
	
	trace("initiate request");
	service.query(query, testOnSuccess, testOnFailure);
	
	trace("suspend test case (if test runner hangs here, something is wrong)");
	testCase.wait();
};



/**
 * TODO doc me
 * @static
 * @asynchronous
 */
flyui.bdgp.Service.ServiceTests.testFindImagesByAnyGeneLabel = function( geneLabel, expectedImages, endpointURL, testCase ) {
	
	flyui.info("Test \"==== flyui.bdgp.Service ServiceTests :: testFindImagesByAnyGeneLabel ("+geneLabel+") ====\" started.");
	
	var service = new flyui.bdgp.Service(endpointURL);
	
	var testOnSuccess = function( images ) {
		trace("resume test case (success)");
		testCase.resume(function() {

			flyui.bdgp.Service.TestData.compareStageArrays(expectedImages, images);
			flyui.bdgp.Service.TestData.compareOrderOfStages(images);
			
		});
	};

	var testOnFailure = function( response ) {
		trace("resume test case (failure)");
		testCase.resume(function() {
			assert.fail("request failed, "+response.status+" "+response.statusText);			
		});
	};

	trace("initiate request");
	service.findImagesByAnyGeneLabel(geneLabel, testOnSuccess, testOnFailure);
	
	trace("suspend test case (if test runner hangs here, something is wrong)");
	testCase.wait();
	
}

/**
 * TODO doc me
 */
flyui.bdgp.Service.ServiceTestCase = function (endpointURL){
	var testCase = new YAHOO.tool.TestCase({
		name: "=== flyui.bdgp.Service ServiceTests ===",
		
		testQuery : function() {
			flyui.bdgp.Service.ServiceTests.testQuery(endpointURL, this);
		},
		
		testFindImagesByAnyGeneLabel_foo : function() {
			var geneLabel = "foo";
			var testData = new flyui.bdgp.Service.TestData();
			var expectedImages = [];
			flyui.bdgp.Service.ServiceTests.testFindImagesByAnyGeneLabel(geneLabel, expectedImages, endpointURL, this);
		},

		testFindImagesByAnyGeneLabel_CG10561 : function() {
			var geneLabel = "CG10561";
			var testData = new flyui.bdgp.Service.TestData();
			var expectedImages = [testData.stage_CG10561];
			flyui.bdgp.Service.ServiceTests.testFindImagesByAnyGeneLabel(geneLabel, expectedImages, endpointURL, this);
		},

		testFindImagesByAnyGeneLabel_CG12750 : function() {
			var geneLabel = "CG12750";
			var testData = new flyui.bdgp.Service.TestData();
			var expectedImages = [
				testData.stage_CG12750_1,
				testData.stage_CG12750_2,
				testData.stage_CG12750_3,
				testData.stage_CG12750_4,
				testData.stage_CG12750_5
			];
			log ("===== expected stages of CG12750: " + expectedImages.length);
			flyui.bdgp.Service.ServiceTests.testFindImagesByAnyGeneLabel(geneLabel, expectedImages, endpointURL, this);
		}
		
	});
	return testCase;
};




// ************************************************************
// TEST DATA
// ************************************************************


/**
 * TODO doc me
 */
flyui.bdgp.Service.TestData = function(){
	
	this.stage_CG10561 = new flyui.bdgp.Stage();
	//this.stage_CG10561.developmentStage = "stage13-16";
	this.stage_CG10561.stageName = "stage13-16";
	this.img_CG10561 = new Object();
	this.img_CG10561.expressions = ["faint ubiquitous"];
	this.img_CG10561.fullImageURL = "http://www.fruitfly.org/insituimages/insitu_images/img_dir_13/insitu13361.jpe";
	this.img_CG10561.thumbnailURL = "http://www.fruitfly.org/insituimages/insitu_images/thumbnails/img_dir_13/insitu13361.jpe";
	this.stage_CG10561.images = [this.img_CG10561];
		
	this.resultSet_CG10561 = {
		"head": {
			"vars": [ "imagepath" , "stage", "developmentStage" , "expression" ]
		} ,
		"results": {
			"bindings": [
				{
					"imagepath": { "type": "uri" , "value": "img_dir_13/insitu13361.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5885" },
					"developmentStage": { "type": "uri" , "value": "stage13-16" } ,
					"expression": { "type": "uri" , "value": "stage13-16"  } 			
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_13/insitu13361.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5885" },
					"developmentStage": { "type": "uri" , "value": "stage13-16" } ,
					"expression": { "type": "uri" , "value": "faint ubiquitous"  } 					
				}
			]
		}
	}
	
//	this.term_5885 = new flyui.bdgp.Term();
//	this.term_5885.name = "stage13-16";
//	this.term_6005 = new flyui.bdgp.Term();
//	this.term_6005.name = "faint ubiquitous";
	
	this.resultSet_CG12750 = {
		"head": {
			"vars": [ "imagepath" , "stage", "developmentStage" , "expression" ]
		} ,
		"results": {
			"bindings": [
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14276.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5884" },
					"developmentStage": { "type": "uri" , "value": "stage11-12" } ,
					"expression": { "type": "uri" , "value": "stage11-12"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14276.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5884" },
					"developmentStage": { "type": "uri" , "value": "stage11-12" } ,
					"expression": { "type": "uri" , "value": "faint ubiquitous"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14276.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5884" },
					"developmentStage": { "type": "uri" , "value": "stage11-12" } ,
					"expression": { "type": "uri" , "value": "salivary gland primordium"  }				
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14277.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5884" },
					"developmentStage": { "type": "uri" , "value": "stage11-12" } ,
					"expression": { "type": "uri" , "value": "stage11-12"  } 	
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14277.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5884" },
					"developmentStage": { "type": "uri" , "value": "stage11-12" } ,
					"expression": { "type": "uri" , "value": "faint ubiquitous"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14277.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5884" },
					"developmentStage": { "type": "uri" , "value": "stage11-12" } ,
					"expression": { "type": "uri" , "value": "salivary gland primordium"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14278.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5884" },
					"developmentStage": { "type": "uri" , "value": "stage11-12" } ,
					"expression": { "type": "uri" , "value": "stage11-12"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14278.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5884" },
					"developmentStage": { "type": "uri" , "value": "stage11-12" } ,
					"expression": { "type": "uri" , "value": "faint ubiquitous"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14278.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5884" },
					"developmentStage": { "type": "uri" , "value": "stage11-12" } ,
					"expression": { "type": "uri" , "value": "salivary gland primordium"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14275.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5882" },
					"developmentStage": { "type": "uri" , "value": "stage7-8" } ,
					"expression": { "type": "uri" , "value": "stage7-8"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14275.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5882" },
					"developmentStage": { "type": "uri" , "value": "stage7-8" } ,
					"expression": { "type": "uri" , "value": "ubiquitous"  }					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14275.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5882" },
					"developmentStage": { "type": "uri" , "value": "stage7-8" } ,
					"expression": { "type": "uri" , "value": "procephalic ectoderm anlage"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14275.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5882" },
					"developmentStage": { "type": "uri" , "value": "stage7-8" } ,
					"expression": { "type": "uri" , "value": "ventral ectoderm primordium P2"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14275.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5882" },
					"developmentStage": { "type": "uri" , "value": "stage7-8" } ,
					"expression": { "type": "uri" , "value": "posterior endoderm primordium P2"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14273.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5882" },
					"developmentStage": { "type": "uri" , "value": "stage7-8" } ,
					"expression": { "type": "uri" , "value": "stage7-8"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14273.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5882" },
					"developmentStage": { "type": "uri" , "value": "stage7-8" } ,
					"expression": { "type": "uri" , "value": "ubiquitous"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14273.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5882" },
					"developmentStage": { "type": "uri" , "value": "stage7-8" } ,
					"expression": { "type": "uri" , "value": "procephalic ectoderm anlage"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14273.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5882" },
					"developmentStage": { "type": "uri" , "value": "stage7-8" } ,
					"expression": { "type": "uri" , "value": "ventral ectoderm primordium P2"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14273.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5882" },
					"developmentStage": { "type": "uri" , "value": "stage7-8" } ,
					"expression": { "type": "uri" , "value": "posterior endoderm primordium P2"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14274.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5882" },
					"developmentStage": { "type": "uri" , "value": "stage7-8" } ,
					"expression": { "type": "uri" , "value": "stage7-8"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14274.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5882" },
					"developmentStage": { "type": "uri" , "value": "stage7-8" } ,
					"expression": { "type": "uri" , "value": "ubiquitous"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14274.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5882" },
					"developmentStage": { "type": "uri" , "value": "stage7-8" } ,
					"expression": { "type": "uri" , "value": "procephalic ectoderm anlage"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14274.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5882" },
					"developmentStage": { "type": "uri" , "value": "stage7-8" } ,
					"expression": { "type": "uri" , "value": "ventral ectoderm primordium P2"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14274.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5882" },
					"developmentStage": { "type": "uri" , "value": "stage7-8" } ,
					"expression": { "type": "uri" , "value": "posterior endoderm primordium P2"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14279.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5885" },
					"developmentStage": { "type": "uri" , "value": "stage13-16" } ,
					"expression": { "type": "uri" , "value": "stage13-16"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14279.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5885" },
					"developmentStage": { "type": "uri" , "value": "stage13-16" } ,
					"expression": { "type": "uri" , "value": "embryonic salivary gland"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14279.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5885" },
					"developmentStage": { "type": "uri" , "value": "stage13-16" } ,
					"expression": { "type": "uri" , "value": "faint ubiquitous"  } 			
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14280.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5885" },
					"developmentStage": { "type": "uri" , "value": "stage13-16" } ,
					"expression": { "type": "uri" , "value": "stage13-16"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14280.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5885" },
					"developmentStage": { "type": "uri" , "value": "stage13-16" } ,
					"expression": { "type": "uri" , "value": "embryonic salivary gland"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14280.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5885" },
					"developmentStage": { "type": "uri" , "value": "stage13-16" } ,
					"expression": { "type": "uri" , "value": "faint ubiquitous"  } 			
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14271.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5880" },
					"developmentStage": { "type": "uri" , "value": "stage1-3" } ,
					"expression": { "type": "uri" , "value": "stage1-3"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14271.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5880" },
					"developmentStage": { "type": "uri" , "value": "stage1-3" } ,
					"expression": { "type": "uri" , "value": "maternal"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14270.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5880" },
					"developmentStage": { "type": "uri" , "value": "stage1-3" } ,
					"expression": { "type": "uri" , "value": "stage1-3"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14270.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5880" },
					"developmentStage": { "type": "uri" , "value": "stage1-3" } ,
					"expression": { "type": "uri" , "value": "maternal"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14272.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5881" },
					"developmentStage": { "type": "uri" , "value": "stage4-6" } ,
					"expression": { "type": "uri" , "value": "stage4-6"  } 					
				},
				{
					"imagepath": { "type": "uri" , "value": "img_dir_14/insitu14272.jpe" } ,
					"stage": {"type": "uri", "value": "http://openflydata.org/id/bdgp/term/5881" },
					"developmentStage": { "type": "uri" , "value": "stage4-6" } ,
					"expression": { "type": "uri" , "value": "ubiquitous"  } 				
				}
			]
		}
	}

	this.stage_CG12750_4 = new flyui.bdgp.Stage();
	this.stage_CG12750_4.stageName = "stage11-12";
	this.stage_CG12750_4.images = new Array();

	this.img_CG12750_1 = new Object();
	this.img_CG12750_1.fullImageURL = "http://www.fruitfly.org/insituimages/insitu_images/img_dir_14/insitu14276.jpe"; 
	this.img_CG12750_1.thumbnailURL = "http://www.fruitfly.org/insituimages/insitu_images/thumbnails/img_dir_14/insitu14276.jpe";
	//this.img_CG12750_1.developmentStage = "stage11-12";
	this.img_CG12750_1.expressions = ["faint ubiquitous", "salivary gland primordium"];
	this.stage_CG12750_4.images.push(this.img_CG12750_1);
	
	this.img_CG12750_2 = new Object();
	this.img_CG12750_2.fullImageURL = "http://www.fruitfly.org/insituimages/insitu_images/img_dir_14/insitu14277.jpe"; 
	this.img_CG12750_2.thumbnailURL = "http://www.fruitfly.org/insituimages/insitu_images/thumbnails/img_dir_14/insitu14277.jpe";
	//this.img_CG12750_2.developmentStage = "stage11-12";
	this.img_CG12750_2.expressions = ["faint ubiquitous","salivary gland primordium"];
	this.stage_CG12750_4.images.push(this.img_CG12750_2);
	
	this.img_CG12750_3 = new Object()
	this.img_CG12750_3.fullImageURL = "http://www.fruitfly.org/insituimages/insitu_images/img_dir_14/insitu14278.jpe"; 
	this.img_CG12750_3.thumbnailURL = "http://www.fruitfly.org/insituimages/insitu_images/thumbnails/img_dir_14/insitu14278.jpe";
	//this.img_CG12750_3.developmentStage = "stage11-12";
	this.img_CG12750_3.expressions = ["faint ubiquitous","salivary gland primordium"];
	this.stage_CG12750_4.images.push(this.img_CG12750_3);
	
	
	/**
	 * Stage 7-8
	 */
	this.stage_CG12750_3 = new flyui.bdgp.Stage();
	this.stage_CG12750_3.stageName = "stage7-8";
	this.stage_CG12750_3.images = new Array();
	
	this.img_CG12750_4 = new Object();
	this.img_CG12750_4.fullImageURL = "http://www.fruitfly.org/insituimages/insitu_images/img_dir_14/insitu14275.jpe"; 
	this.img_CG12750_4.thumbnailURL = "http://www.fruitfly.org/insituimages/insitu_images/thumbnails/img_dir_14/insitu14275.jpe";
	//this.img_CG12750_4.developmentStage = "stage7-8";
	this.img_CG12750_4.expressions = ["ubiquitous", "procephalic ectoderm anlage", "ventral ectoderm primordium P2",
		"posterior endoderm primordium P2"];
	this.stage_CG12750_3.images.push(this.img_CG12750_4);
	

	this.img_CG12750_5 = new Object();
	this.img_CG12750_5.fullImageURL = "http://www.fruitfly.org/insituimages/insitu_images/img_dir_14/insitu14273.jpe"; 
	this.img_CG12750_5.thumbnailURL = "http://www.fruitfly.org/insituimages/insitu_images/thumbnails/img_dir_14/insitu14273.jpe";
	//this.img_CG12750_5.developmentStage = "stage7-8";
	this.img_CG12750_5.expressions = ["ubiquitous", 
		"procephalic ectoderm anlage",
		"ventral ectoderm primordium P2",
		"posterior endoderm primordium P2"];
	this.stage_CG12750_3.images.push(this.img_CG12750_5);

	this.img_CG12750_6 = new Object();
	this.img_CG12750_6.fullImageURL = "http://www.fruitfly.org/insituimages/insitu_images/img_dir_14/insitu14274.jpe"; 
	this.img_CG12750_6.thumbnailURL = "http://www.fruitfly.org/insituimages/insitu_images/thumbnails/img_dir_14/insitu14274.jpe";
	//this.img_CG12750_6.developmentStage = "stage7-8";
	this.img_CG12750_6.expressions = ["ubiquitous", 
		"procephalic ectoderm anlage",
		"ventral ectoderm primordium P2",
		"posterior endoderm primordium P2"];
	this.stage_CG12750_3.images.push(this.img_CG12750_6);
	
	/**
	 * Stage13-16
	 */
	this.stage_CG12750_5 = new flyui.bdgp.Stage();
	this.stage_CG12750_5.stageName = "stage13-16";
	this.stage_CG12750_5.images = new Array();
	
	this.img_CG12750_7 = new Object();
	this.img_CG12750_7.fullImageURL = "http://www.fruitfly.org/insituimages/insitu_images/img_dir_14/insitu14279.jpe"; 
	this.img_CG12750_7.thumbnailURL = "http://www.fruitfly.org/insituimages/insitu_images/thumbnails/img_dir_14/insitu14279.jpe";
	//this.img_CG12750_7.developmentStage = "stage13-16";
	this.img_CG12750_7.expressions = ["embryonic salivary gland","faint ubiquitous"];
	this.stage_CG12750_5.images.push(this.img_CG12750_7);
	
	
	this.img_CG12750_8 = new Object();
	this.img_CG12750_8.fullImageURL = "http://www.fruitfly.org/insituimages/insitu_images/img_dir_14/insitu14280.jpe"; 
	this.img_CG12750_8.thumbnailURL = "http://www.fruitfly.org/insituimages/insitu_images/thumbnails/img_dir_14/insitu14280.jpe";
	//this.img_CG12750_8.developmentStage = "stage13-16";
	this.img_CG12750_8.expressions = ["embryonic salivary gland", "faint ubiquitous"];
	this.stage_CG12750_5.images.push(this.img_CG12750_7);
	
	/**
	 * Stage1-3
	 */
	this.stage_CG12750_1 = new flyui.bdgp.Stage();
	this.stage_CG12750_1.stageName = "stage1-3";
	this.stage_CG12750_1.images = new Array();
	
	this.img_CG12750_9 = new Object();
	this.img_CG12750_9.fullImageURL = "http://www.fruitfly.org/insituimages/insitu_images/img_dir_14/insitu14271.jpe"; 
	this.img_CG12750_9.thumbnailURL = "http://www.fruitfly.org/insituimages/insitu_images/thumbnails/img_dir_14/insitu14271.jpe";
//	this.img_CG12750_9.developmentStage = "stage1-3";
	this.img_CG12750_9.expressions = ["maternal"];
	this.stage_CG12750_1.images.push(this.img_CG12750_9);
	
	this.img_CG12750_10 = new Object();
	this.img_CG12750_10.fullImageURL = "http://www.fruitfly.org/insituimages/insitu_images/img_dir_14/insitu14270.jpe"; 
	this.img_CG12750_10.thumbnailURL = "http://www.fruitfly.org/insituimages/insitu_images/thumbnails/img_dir_14/insitu14270.jpe";
//	this.img_CG12750_10.developmentStage = "stage1-3";
	this.img_CG12750_10.expressions = ["maternal"];
	this.stage_CG12750_1.images.push(this.img_CG12750_10);

	/**
	 * Stage4-6
	 */
	this.stage_CG12750_2 = new flyui.bdgp.Stage();
	this.stage_CG12750_2.stageName = "stage4-6";
	this.stage_CG12750_2.images = new Array();
	
	this.img_CG12750_11 = new Object();
	this.img_CG12750_11.fullImageURL = "http://www.fruitfly.org/insituimages/insitu_images/img_dir_14/insitu14272.jpe"; 
	this.img_CG12750_11.thumbnailURL = "http://www.fruitfly.org/insituimages/insitu_images/thumbnails/img_dir_14/insitu14272.jpe";
	this.img_CG12750_11.developmentStage = "stage4-6";
	this.img_CG12750_11.expressions = ["ubiquitous"];
	this.stage_CG12750_2.images.push(this.img_CG12750_11);
	
	
	//	this.stage_5880 = new flyui.bdgp.Stage();
	//	this.stage_5880.name = "stage1-3";
	
	//	this.stage_5881 = new flyui.bdgp.Stage();
	//	this.stage_5882.name = "stage4-6";
	
	//	this.stage_5882 = new flyui.bdgp.Stage();
	//	this.stage_5882.name = "stage7-8";
	
	//	this.stage_5883 = new flyui.bdgp.Stage();
	//	this.stage_5883.name = "stage9-10";
	
	//	this.stage_5884 = new flyui.bdgp.Stage();
	//	this.stage_5884.name = "stage11-12";
	
	//	this.stage_5885 = new flyui.bdgp.Stage();
	//	this.stage_5885.name = "stage13-16";
	
}


/**
 * Compare two image objects.
 * @param {flyui.bdgp.Image} expected
 * @param {flyui.bdgp.Image} actual
 */
flyui.bdgp.Service.TestData.compareImages = function( expected, actual ) {
	
	trace("test bdgp full image url");
	assert.areEqual(expected.fullImageURL, actual.fullImageURL, "full image URL not expected");
	
	trace("test bdgp thumbnail url");
	assert.areEqual(expected.thumbnailURL, actual.thumbnailURL, "thumbnail URL not expected");
	
	trace("test bdgp image expression annotation");
	assert.areEqual(expected.expressions.length, actual.expressions.length, "number of expression annotation not expected");	
	assert.isTrue(flyui.util.arrayMembersAreEqual(expected.expressions, actual.expressions), "expressions not as expected");
	
}



/**
 * TODO doc me
 */
flyui.bdgp.Service.TestData.compareImageArrays = function( expecteds, actuals ) {

	trace("comparing image arrays");

	assert.areEqual(expecteds.length, actuals.length, "number of images not as expected");
	
	var n = actuals.length;
	for (var i=0; i<n; i++) {
		var expected = expecteds[i];
		var found = false;
		for (var j=0; j<n; j++) {
			var image = actuals[j];
			if (image.fullImageURL == expected.fullImageURL) {
				found = true;
				flyui.bdgp.Service.TestData.compareImages(expected, image);
			}
		}
		assert.isTrue(found, "did not find expected image "+expected.fullImageURL);
	}
	
}

flyui.bdgp.Service.TestData.compareStageArrays = function( expecteds, actuals ){
	trace("comparing stage arrays");
	
	assert.areEqual(expecteds.length, actuals.length, "number of stages not as expected");
	
	var n = actuals.length;
	for (var i=0; i<n; i++) {
		var expected = expecteds[i];
		var found = false;
		for (var j=0; j<n; j++) {
			var stage = actuals[j];
			if (stage.stageName == expected.stageName) {
				found = true;
				flyui.bdgp.Service.TestData.compareImageArrays(expected.images, stage.images);
			}
		}
		assert.isTrue(found, "did not find expected stage "+expected.stageName);
	}
};

flyui.bdgp.Service.TestData.compareOrderOfStages = function( stages ) {
	log ("checking stages are correctedly order in the results", "test");
	for (var i =0; i < stages.length-1; i ++){
		assert.isTrue(stages[i].stageURI<stages[i+1].stageURI, stages[i].stageURI + " should be returned after " + stages[i+1].stageURI);
	}
}


// ************************************************************
// TEST SUITE AND RUNNER
// ************************************************************


/** 
 * Construct a YUI test suite for the flyui.bdgp.Service module.
 * @param {String} endpointURL URL of service
 * @return a YUI test suite
 * @type YAHOO.tool.TestSuite
 */
flyui.bdgp.Service.TestSuite = function(endpointURL) {
	var suite = new YAHOO.tool.TestSuite("== flyui.bdgp.Service Test Suite ==");
	suite.add(flyui.bdgp.Service.ModuleTestCase());
	suite.add(flyui.bdgp.Service.ImageTestCase());
	suite.add(flyui.bdgp.Service.ServiceTestCase(endpointURL));
	return suite;
}


/** 
 * Run the flyui.bdgp.Service test suite.
 * @param {String} endpointURL URL of service
 */
flyui.bdgp.Service.runTests = function(endpointURL) {
	trace("flyui.bdgp.Service :: running tests");
	YAHOO.tool.TestRunner.add(flyui.bdgp.Service.TestSuite(endpointURL));
	YAHOO.tool.TestRunner.run();
}